﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace JuCloudy.Platform.UserControls
{
    public partial class ArcBar : UserControl
    {
        public ArcBar()
        {
            InitializeComponent();
            PercentProperty = DependencyProperty.Register("Percent", typeof(Double), typeof(ArcBar),
                new PropertyMetadata(100.00, new PropertyChangedCallback((obj, e) =>
                {
                    if ((Double)e.NewValue >= 0 && (Double)e.NewValue <= 100)
                    {
                        this.PlayStory((Double)e.OldValue * 3.6, (Double)e.NewValue * 3.6);
                        if (this.ShowPercent)
                            this._txt.Text = e.NewValue.ToString();
                    }
                })));

            ArcThicknessProperty = DependencyProperty.Register("BorderThickness", typeof(Double), typeof(ArcBar),
                new PropertyMetadata(5.0, new PropertyChangedCallback((obj, e) =>
                {
                    this.arc_main.ArcThickness = (Double)e.NewValue;
                })));

            BorderBrushProperty = DependencyProperty.Register("BorderBrush", typeof(Brush), typeof(ArcBar),
                new PropertyMetadata(new SolidColorBrush(Colors.White), new PropertyChangedCallback((obj, e) =>
                {
                    this.arc_main.Stroke = (Brush)e.NewValue;
                })));

            BackgroundProperty = DependencyProperty.Register("Background", typeof(Brush), typeof(ArcBar),
                new PropertyMetadata(new SolidColorBrush(Colors.White), new PropertyChangedCallback((obj, e) =>
                {
                    this.arc_main.Fill = (Brush)e.NewValue;
                })));

            PaddingProperty = DependencyProperty.Register("Padding", typeof(Thickness), typeof(ArcBar),
                new PropertyMetadata(new Thickness(0, 0, 0, 0), new PropertyChangedCallback((obj, e) =>
                {
                    this._img.Margin = (Thickness)e.NewValue;
                })));

            ForegroundProperty = DependencyProperty.Register("Foreground", typeof(Brush), typeof(ArcBar),
                new PropertyMetadata(new SolidColorBrush(Colors.White), new PropertyChangedCallback((obj, e) =>
                {
                    this._txt.Foreground = (Brush)e.NewValue;
                })));

            FontSizeProperty = DependencyProperty.Register("FontSize", typeof(Double), typeof(ArcBar),
                new PropertyMetadata(30.0, new PropertyChangedCallback((obj, e) =>
                {
                    this._txt.FontSize = (Double)e.NewValue;
                })));

            ShowPercentProperty = DependencyProperty.Register("ShowPercent", typeof(bool), typeof(ArcBar),
                new PropertyMetadata(true));

            IsIndeterminateProperty = DependencyProperty.Register("IsIndeterminate", typeof(bool), typeof(ArcBar),
                new PropertyMetadata(false, new PropertyChangedCallback((obj, e) =>
                {
                    if ((bool)e.NewValue == true)
                        PlayIndeterminateStory();
                    else StopIndeterminateStory();
                })));

            SpeedRatioProperty = DependencyProperty.Register("SpeedRatio", typeof(Double), typeof(ArcBar),
                new PropertyMetadata(1.0));
        }

        private DependencyProperty PercentProperty;
        public Double Percent
        {
            get { return (Double)GetValue(PercentProperty); }
            set { SetValue(PercentProperty,value); }
        }

        private DependencyProperty ArcThicknessProperty;
        public Double ArcThickness
        {
            get { return (Double)GetValue(ArcThicknessProperty); }
            set { SetValue(ArcThicknessProperty, value); }
        }

        private new DependencyProperty BorderBrushProperty;
        public new Brush BorderBrush
        {
            get{return (Brush)GetValue(BorderBrushProperty);}
            set { SetValue(BorderBrushProperty,value); }
        }

        private new DependencyProperty BackgroundProperty;
        public new Brush Background
        {
            get { return (Brush)GetValue(BackgroundProperty); }
            set { SetValue(BackgroundProperty, value); }
        }

        private new DependencyProperty PaddingProperty;
        public new Thickness Padding
        {
            get { return (Thickness)GetValue(PaddingProperty); }
            set { SetValue(PaddingProperty, value); }
        }

        private new DependencyProperty ForegroundProperty;
        public new Brush Foreground
        {
            get { return (Brush)GetValue(ForegroundProperty); }
            set { SetValue(ForegroundProperty, value); }
        }

        private new DependencyProperty FontSizeProperty;
        public new Double FontSize
        {
            get { return (Double)GetValue(FontSizeProperty); }
            set { SetValue(FontSizeProperty, value); }
        }

        public String Text
        {
            get { return this._txt.Text; }
            set { this._txt.Text = value; }
        }

        private DependencyProperty ShowPercentProperty;
        public bool ShowPercent
        {
            get { return (bool)GetValue(ShowPercentProperty); }
            set{SetValue(ShowPercentProperty,value);}
        }

        private DependencyProperty IsIndeterminateProperty;
        public bool IsIndeterminate
        {
            get { return (bool)GetValue(IsIndeterminateProperty); }
            set { SetValue(IsIndeterminateProperty, value); }
        }

        private DependencyProperty SpeedRatioProperty;
        public Double SpeedRatio
        {
            get { return (Double)GetValue(SpeedRatioProperty); }
            set { SetValue(SpeedRatioProperty, value); }
        }

        private Storyboard GetStory(Double OldValue,Double NewValue)
        {
            arc_main.RenderTransform = new CompositeTransform();
            var story = new Storyboard();
            DoubleAnimation transform = new DoubleAnimation();
            transform.From = OldValue;
            transform.To = NewValue;
            transform.SpeedRatio = this.SpeedRatio;
            transform.Duration = new Duration(TimeSpan.FromMilliseconds(Math.Abs(NewValue - OldValue) * 25));
            Storyboard.SetTarget(transform, arc_main);
            Storyboard.SetTargetProperty(transform, new PropertyPath("EndAngle"));
            story.Children.Add(transform);
            return story;
        }

        private void PlayStory(Double OldValue,Double NewValue)
        {
            if (!this.IsIndeterminate)
            {
                try
                {
                    GetStory(OldValue, NewValue).Begin();
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
        }

        private Storyboard GetIndeterminateStory()
        {
            arc_main.RenderTransform = new CompositeTransform();
            var story = new Storyboard();
            DoubleAnimation transform = new DoubleAnimation();
            transform.From = 0;
            transform.To = 20;
            transform.SpeedRatio = this.SpeedRatio;
            transform.Duration = new Duration(TimeSpan.FromMilliseconds(500));
            Storyboard.SetTarget(transform, arc_main);
            Storyboard.SetTargetProperty(transform, new PropertyPath("EndAngle"));

            DoubleAnimation transform2 = new DoubleAnimation();
            transform2.From = 0;
            transform2.To = 360;
            transform2.SpeedRatio = this.SpeedRatio;
            transform2.Duration = new Duration(TimeSpan.FromMilliseconds(360 * 50));
            transform2.BeginTime = TimeSpan.FromMilliseconds(500);
            Storyboard.SetTarget(transform2, arc_main);
            Storyboard.SetTargetProperty(transform2, new PropertyPath("(UIElement.RenderTransform).(CompositeTransform.Rotation)"));
            transform2.RepeatBehavior = RepeatBehavior.Forever;

            story.Children.Add(transform);
            story.Children.Add(transform2);
            return story;
        }
        private Storyboard IndeterminateStory=null;
        private void PlayIndeterminateStory()
        {
            if (this.IsIndeterminate)
            {
                try
                {
                   IndeterminateStory = GetIndeterminateStory();
                   IndeterminateStory.Begin();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }
            }
        }
        private void StopIndeterminateStory()
        {
            try
            {
                IndeterminateStory.Stop();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
    }
}
